$$ \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \renewcommand{\mod}{\,\mathrm{mod}\,} \renewcommand{\div}{\,\mathrm{div}\,} \newcommand{\metar}{\,\mathrm{m}} \newcommand{\cm}{\,\mathrm{cm}} \newcommand{\dm}{\,\mathrm{dm}} \newcommand{\litar}{\,\mathrm{l}} \newcommand{\km}{\,\mathrm{km}} \newcommand{\s}{\,\mathrm{s}} \newcommand{\h}{\,\mathrm{h}} \newcommand{\minut}{\,\mathrm{min}} \newcommand{\kmh}{\,\mathrm{\frac{km}{h}}} \newcommand{\ms}{\,\mathrm{\frac{m}{s}}} \newcommand{\mss}{\,\mathrm{\frac{m}{s^2}}} \newcommand{\mmin}{\,\mathrm{\frac{m}{min}}} \newcommand{\smin}{\,\mathrm{\frac{s}{min}}} $$

Prijavi problem


Obeleži sve kategorije koje odgovaraju problemu

Još detalja - opišite nam problem


Uspešno ste prijavili problem!
Status problema i sve dodatne informacije možete pratiti klikom na link.
Nažalost nismo trenutno u mogućnosti da obradimo vaš zahtev.
Molimo vas da pokušate kasnije.

Аритметика

У овој глави приказаћемо како се могу решавати разни задаци у којима се врше основна аритметичка израчунавања. Такви задаци се обично срећу у математици, физици и хемији, а коришћење рачунара олакшава њихово решавање, јер је потребно само записати формуле на основу којих се долази до решења, док је рачунар тај који преузима посао извршавања рачунских операција.

Елементи програмског језика

Пре задатака укратко ћемо описати елементе програмског језика Пајтон које ћемо користити у решењима у овој глави.

Први програм

Програм који на екран исписује поруку Zdravo svete! је на Пајтону врло једноставан:

print("Zdravo svete!")

Програм се састоји само од једне наредбе и то је наредба print којом се текст наведен између наводника исписује на екран. Обратимо пажњу на то да језик Пајтон прави разлику између малих и великих слова и врло је важно да ли је нешто написано малим или великим словом.

Коментари

У коду можемо писати коментаре – текст којим се објашњава шта се у неком делу програма ради и који је намењен ономе ко буде читао програм (или ономе ко је тај програм писао, ако некада касније буде потребе да га доради или преправи). Рачунар игнорише коментаре у програмима и за извршавање је свеједно да ли се у програму налазе коментари или не. У језику Пајтон коментар почиње навођењем ознаке # и простире се до краја тог реда (овакве коментаре често називамо линијским коментарима). Можемо писати и коментаре који се протежу кроз неколико суседних редова (тзв. вишелинијске коментаре) и они почињу и завршавају се ознаком '''. У овој збирци ћемо се трудити да наводимо коментаре што више (често много више него што је то уобичајена пракса), да бисмо вам помогли у разумевању приложених решења.

Испис, учитавање, променљиве, типови

Испис у конзолу се врши наредбом print("..."), при чему текст који се исписује може да се наведе између једноструких или двоструких наводника. У једном програму може бити и више позива ове наредбе. На пример,

print("Učim da programiram.")
print("Koristim programski jezik Pajton.")
print("Zdravo svima!")

Када се програм покрене, наведене линије се исписују једна испод друге.

Učim da programiram. Koristim programski jezik Pajton. Zdravo svima!

Ако се жели да се након исписа текста остане у истом реду, онда се функцији print додаје аргумент end=''. Тако програм

print("Učim da programiram ", end='')
print("u programskom jeziku Pajton.")

исписује текст

Učim da programiram u programskom jeziku Pajton.

После прве наредбе се није прешло у наредни ред, па се наставак реченице појавио у истом реду, непосредно након размака који је наведен као последњи карактер у тексту који се исписује првом наредбом.

Веома интересантно, текст се у програмском језику Пајтон може “сабирати” слично као што се у математици сабирају бројеви. Уместо сабирања, наравно, врши се надовезивање текста. Тако је збир "Zdravo" + " " + "svete" + "!" једнак тексту "Zdravo svete!". Ово се може користити приликом исписа. Наредба

print("Zdravo" + " " + "svete" + "!")

проузрокује испис текста

Zdravo svete!

Текст може да се учита од корисника. Размотримо наредни програм.

print("Kako se zoveš?")
ime = input()
print("Zdravo, ti se zoveš " + ime)

У првој наредби, помоћу функције print на екран исписујемо текст Kako se zoveš?. У другој наредби помоћу функције input() учитавамо једну линију текста од корисника. Наравно, очекујемо да корисник унесе своје име (мада може да унесе шта год жели - наш програм неће приметити разлику). Текст који корисник унесе морамо негде да упамтимо, да бисмо га у трећој линији исписали на екран (опет помоћу функције print). Да бисмо упамтили разне вредности (у овом примеру то је текст који је корисник унео, а у наредним примерима ће то бити разни бројеви са којима ћемо вршити различита израчунавања) користимо променљиве. У наведеном примеру користимо променљиву под називом ime и у њу смештамо текст који је корисник унео. Променљиве можемо замислити као кутијице у којима се чувају различите вредности. У сваком тренутку стара вредност може бити избачена из кутијице и у кутијицу може бити уписана нека нова вредност. Пајтон спада у групу такозваних динамички типизираних језика што значи да променљиве добијају тип од вредности коју садрже, а могу да прихвате вредност било којег типа. Променљиве могу променом вредности да промене и тип. У првим програмима користићемо следеће основне типове података.

тип опис пример
str текст (ниска карактера) "Zdravo"
int цео број 1234
float реалан број 3.141
bool логичка вредност True или False

У Пајтону целобројне променљиве могу да чувају веома велике и веома мале бројеве (сам језик Пајтон не поставља никаква ограничења за величину целих бројева које може да користи). Насупрот томе, за реалне бројеве (тип float) постоје извесна ограничења за распон (величину) и прецизност (број значајних цифара) у складу са стандардом који користе и други програмски језици. Овим ограничењима се за сада нећемо бавити јер за тиме на почетку нема потребе.

Када променљивој први пут у програму додељујемо вредност, му ту променљиву дефинишемо. То значи да је променљивој придружен неки простор у меморији рачунара и да је у тај простор уписана вредност променљиве. У претходном примеру променљива ime је дефинисана наредбом ime = input().

Наравно, приликом доделе могуће је променљивама додељивати и неке конкретне вредности (кажемо константе). На пример

ime = "Pera"

Именовање променљивих треба да тече у складу са њиховим значењем (пожељно је избегавати кратка, неинформативна имена попут a, b, x, y, осим ако из контекста програма није потпуно јасно шта би те променљиве могле да означавају). Имена променљивих не смеју да садрже размаке и морају бити састављена само од слова, цифара и доње црте тј. подвлаке (карактера _), али не могу почињати цифром.

Променљиве се могу дефинисати и помоћу вредности других типова. На пример, овако можемо да дефинишемо три променљиве, које су на почетку целобројног типа:

a, b, c = 3, 2, 4

Када су у питању реалне вредности, наглашавамо да се оне наводе са децималном тачком (у складу са правописом енглеског језика), а не запетом (у складу са правописом српског језика).

pi = 3.14159265

Наредба исписа коју смо остваривали позивом функције print може бити употребљена и за испис бројевних, па и логичких вредности. На пример, наредним наредбама

print(123)
x = 5
print(x)
print(12.345)
pi = 3.14159265
print(pi)

исписује се

123 5 12.345 3.14159265

Приликом исписа реалних бројева могуће је у приказу заокружити исписане вредности на одређени број децимала. Један начин да се то уради је да се вредности пре исписа претворе у текст, функцијом format, на следећи начин.

pi = 3.14159265
s = format(pi, '.2f')
print(s)

или краће:

pi = 3.14159265
print(format(pi, '.2f'))

Овим добијамо исписан резултат 3.14. Број иза тачке одређује број децималних места у резултату.

Када је потребно да се прецизно контролише испис неколико бројева у једном реду, може се користити још један облик форматирања. Када се испред ниске у функцији print наведе слово f, онда унутар ниске у витичастим заградама може да се наведе име променљиве и опис исписивања, што ће при исписивању бити замењено вредношћу променљиве приказаном у скаду са наведеним описом.

ime1 = 'Petar'
prosek1 = 4.721876435
ime2 = 'Sava'
prosek2 = 4.832987645
print(f'{ime1} ima prosek {prosek1:.2f}, a {ime2} ima prosek {prosek2:.2f}.')

Овим програмом се исписује:

Petar ima prosek 4.72, a Sava ima prosek 4.83.

Опис формата :.2f је могао да буде и изостављен, а у том случају би одговарајући реални бројеви били исписани без форматирања.

Учитавање бројева није директно подржано у језику Пајтон. Кориснички унос се увек третира као текст (ниска карактера), а ако представља исправан запис целог или реалног броја, он се може накнадно конвертовати у бројевну вредност. Један од начина да се текст конвертује у целобројну вредност је функција int, а у реалну вредност је функција float. Тако ћемо целе и реалне бројеве уносити на следећи начин.

x = int(input())
y = float(input())

Нагласимо да се приликом уноса на овај начин очекује да свака унета линија текста садржи по један исправно записан број. Ако се при оваквом учитавању у једној линији унесу два броја раздвојена размаком, долази до грешке при претварању текста у број. Учитавање више бројева у једном реду је нешто сложеније и није неопходно да се сасвим разуме већ сада. Уместо тога, одговарајући запис можемо усвојити као идиом, ставити га на “јавно дозвољене пушкице” и за сада користити као такав. Два цела броја бисмо у једном реду улаза учитали на следећи начин.

reci = input().split()
x = int(reci[0])
y = int(reci[1])

Три цела броја бисмо из исте линије учитали веома слично.

reci = input().split()
x = int(reci[0])
y = int(reci[1])
z = int(reci[2])

У првој линији се учитава линија текста, а онда се помоћу split она дели на појединачне речи, које се смештају у листу којој дајемо име reci. У овом примеру reci је променљива која садржи листу чији су елементи ниске (стрингови). Након тога узимамо једну по једну реч из те листе (прва се налази на позицији 0, друга на позицији 1 и тако даље) и сваку од њих конвертујемо у цео број и памтимо у посебној променљивој.

На крају, рецимо да је приликом исписа могуће комбиновати текст и бројевне вредности. На пример,

print("Vrednost broja pi je " + str(3.1415926))

или једноставније:

print("Vrednost broja pi je", 3.1415926)

Један начин комбинавања текста и бројева при испису је да бројеве конвертујемо у текст помоћу функције str или format, а затим добијене текстове надовежемо један на други операцијом +.

Други начин је да вредности различитог (или истог) типа само наведемо као параметре функције print. Приликом исписивања ће између ових вредности бити приказан по један размак. На овај начин се може комбиновати и више вредности:

print("Unesi jedan ceo broj: ")
ceo_broj = int(input())
print("Unesi jedan realan broj: ")
realan_broj = float(input())
print("Ceo broj: ", ceo_broj, "Realan broj: ", realan_broj)

Основне аритметичке операције и изрази

Програми које смо до сада срели су врло једноставни и зато нису нарочито интересантни. Могли смо само да учитамо податке и да их испишемо у неизмењеном облику.

Рачунар је машина која обрађује податке, тј. која примењујући рачунске операције на основу улазних података добија излазне. У рачунару је све записано помоћу бројева и на најнижем нивоу се све операције своде на основне операције над бројевима. Рачунар или компјутер (енгл. computer) је справа која рачуна тј. справа која је направљена тако да може веома брзо и ефикасно да изводи рачунске операције над бројевима. Рачунање се назива и аритметика (од грчке речи ἀριθμός тј. аритмос која значи број, бројање, рачунање), а рачунске операције се називају и аритметичке операције.

  • Основна аритметичка операција је сабирање. Збир бројева \(3\) и \(5\) се у математици представља као \(3 + 5\). У програмском језику Пајтон користи се идентичан запис \(3 + 5\). Сабирање је применљиво и на целе и на реалне бројеве (а као што смо видели - и на ниске, које се тиме дописују једна на другу). На пример, програм који учитава и сабира два цела броја може бити написан на следећи начин.

    x = int(input())
    y = int(input())
    print(x + y)
  • Поред сабирања можемо разматрати одузимање. Разлика бројева \(8\) и \(2\) се у математици представља као \(8 - 2\). У програмском језику Пајтон користи се идентичан запис \(8 - 2\). Одузимање је применљиво и на целе и на реалне бројеве.

  • Још једна од основних операција је и множење. Производ бројева \(4\) и \(6\) се у математици представља као \(4 \cdot 6\). У програмском језику Пајтон множење се означава помоћу оператора * и производ бројева 4 и 6 се записује као 4 * 6.

  • У програмском језику Пајтон, наравно, можемо и да делимо, да израчунавамо остатак при дељењу и цео део количника. Због одређених специфичности ових операција на скупу целих бројева, ми ћемо се у почетку бавити само операцијом дељења реалних бројева, док ћемо се целобројним дељењем детаљније бавити касније. Дељење бројева се врши помоћу оператора / и количник бројева 7,2 и 6,4 се записује као 7.2 / 6.4. Целобројно дељење се врши помоћу оператора // и целобројни количник бројева \(14\) и \(4\) се записује као 14 // 4 и има вредност \(3\). Остатак при дељењу два цела броја се може израчунати оператором %. На пример, вредност израза 14 % 4 једнака је 2. Ако желимо да одредимо реалан количник два цела броја, користимо “обично” дељење: 14/4 има вредност 3.5.

Слично као и у математици, од константних вредности и променљивих, применом оператора и заграда граде се изрази. Приоритет оператора је усклађен са уобичајеним приоритетом у математици, па је приоритет оператора *, /, // и % виши од приоритета оператора + и -, док су сви наведени оператори лево асоцијативни (рачунске операције истог приоритета се изводе с лева на десно). Приоритет и асоцијативност се могу применити навођењем заграда.

У првим програмима ћемо се трудити да приликом извођења операција не мешамо податке различитог типа. Ипак, нагласимо да ако је у изразу један број реалан, а други цео, пре извођења операција се тај цео број претвара у реалан и операција се извршава над реалним бројевима.

Уграђене математичке функције

У многим конкретним применама поред основних аритметичких операција примењују се и неке мало напредније математичке функције и неке чувене математичке константе (нпр. \(\pi\)). У језику Пајтон оне су означене са math (то су константе модула math, али у овом тренутку нам та прецизна дефиниција није значајна).

  • abs(x) - израчунава апсолутну вредност \(|x|\);
  • math.pow(x, y) - израчунава степен \(x^y\), при чему се може применити и за израчунавање корена (не само квадратних) знајући да је \(\sqrt[n]{x} = x^{\frac{1}{n}}\);
  • math.sqrt(x) - израчунава квадратни корен \(\sqrt{x}\);
  • math.pi - константа \(\pi\);

Поред ових, на располагању су нам и тригонометријске функције (синус, косинус, …), њихове инверзне функције, логаритамска функција, експоненцијална функција и слично, али њих нећемо користити у почетним задацима.

Дефинисање функција

Поред библиотечких функција које су нам на располагању, програмски језици, па и језик Пајтон програмеру дају могућност да дефинишу функције, што доприноси избегавању поновљених делова програма, декомпозицији проблема на мање потпроблеме и бољој организацији кода. Функције можемо замислити слично као у математици. Оне обично за неколико улазних параметара израчунавају једну резултујућу вредност. На пример, наредна функција израчунава обим правоугоника датих страница.

## funkcija izračunava obim pravougaonika cije su stranice dužine a i b
def obim(a, b):
   return 2*a + 2*b # formula za obim pravougaonika

## učitavamo dužine stranica pravougaonika
a = float(input())
b = float(input())
## izračunavamo obim pomoću definisane funkcije
O = obim(a, b)
## ispisujemo izračunati obim
print(O)

Прва линија def obim(a, b): започиње дефиницију функције и у њој се каже да се функција назива obim (иако није обавезно, у језику Пајтон пожељно је да имена функција почињу малим словом), и да прима две улазне вредности (два параметра) који се називају a и b. У телу функције (оно се пише увучено) се описује како се резултат израчунава на основу улазних вредности. Када је коначан резултат израчунат, функција враћа тај резултат помоћу наредбе return. Након исправне дефиниције следи позив функције. У претходном примеру позив је извршен у склопу доделе O = obim(a, b). У позиву се наводе аргументи којима се иницијализује вредност параметара. У овом случају то су вредности променљивих које су учитане са тастатуре. Аргументи могу бити и изрази или константне вредности (параметри морају бити променљиве). На пример, допуштен је позив Obim(5.0, 7.0).

Унутар функције можемо декларисати и користити и променљиве у којима чувамо међурезултате. На пример, можемо дефинисати функцију за израчунавање површине једнакостраничног троугла дате дужине странице.

def povrsina_jednakostranicnog_trougla(a):
   # izračunavamo visinu trougla
   h = a * math.sqrt(3) / 2.0
   # izračunavamo površinu na osnovu dužine stranice i visine
   P = a * h / 2.0
   # vraćamo konačan rezultat
   return P

Овом функцијом је дефисан начин да се израчуна површина једнакостраничног троугла и када нам год то надаље затреба у програму (а у неком математичком задатку то може бити потребно више пута), можемо само позвати функцију и добити жељени резултат.

Постоје и функције које не враћају вредност. Такве функције се некада називају процедурама - оне садрже неки део алгоритма, који се извршава њиховим позивом (на пример, нешто израчунају и резултат испишу на екран). Тако се у следећем примеру дефинише функција ukrasi_tekst, која око датог текста исписује украсне линије, а затим се та функција позива неколико пута у програму.

def ukrasi_tekst(tekst):
   print("---------------------------------------")
   print(tekst)
   print("---------------------------------------")
   
ukrasiTekst("Dobar dan!")
ukrasiTekst("Zdravo, svima!")
ukrasiTekst("Dovidjenja!")

Више повратних вредности - излазни параметри

Параметри функције су њене улазне вредности (исто као и у математици), док је вредност враћена помоћу return њена излазна вредност. Функција обично има било који број улазних и једну излазну вредност (и ово одговара појму функције у математици). Међутим, у програмирању некада имамо потребу да дефинишемо функције које враћају више од једне вредности. У Пајтону се то ради веома једноставно - само се после речи return наведу вредности раздвојене зарезима. На пример, наредна функција конвертује дужину задату само у центиметрима у дужину задату у метрима и центиметрима.

def u_metre_i_centimetre(duzina):
   metri = duzina // 100
   centimentri = duzina % 100
   return metri, centimentri

Позив ове функције се врши на следећи начин.

m, cm = u_metre_i_centimetre(273)

Након овог позива, вредност променљиве m ће бити 2, а cm ће бити 73.

Исти ефекат се постиже и ако се користе уређени парови тј. уређене n-торке.

def u_metre_i_centimetre(duzina):
   metri = duzina // 100
   centimentri = duzina % 100
   return (metri, centimentri)
   
(m, cm) = u_metre_i_centimetre(273)